css: Avoid excessive shadow rendering
authorMatthias Clasen <mclasen@redhat.com>
Tue, 2 Dec 2014 13:29:24 +0000 (08:29 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 2 Dec 2014 13:29:24 +0000 (08:29 -0500)
The shadow rendering code had code to exit early if we determine
that the shadow is entirely clipped away. Unfortunately, the check
based on cairo clip extents fails for any clip regions that are
more complicated than axis-aligned rectangles, and we are using
a hollow rounded rectangle here. So, instead, do the check manually,
using the just-introduced API in GtkRoundedBox.

gtk/gtkcssshadowvalue.c

index d3847ba627675f5f8d3de221969e4aee51d339c7..4ea2f76114f0907c8bcc106181588819d4baaa4b 100644 (file)
@@ -638,9 +638,15 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue   *shadow,
 {
   GtkRoundedBox box, clip_box;
   double spread, radius, clip_radius, x, y, outside;
+  double x1, y1, x2, y2;
 
   g_return_if_fail (shadow->class == &GTK_CSS_VALUE_SHADOW);
 
+  cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
+  if ((shadow->inset && !_gtk_rounded_box_intersects_rectangle (padding_box, x1, y1, x2, y2)) ||
+      (!shadow->inset && _gtk_rounded_box_contains_rectangle (padding_box, x1, y1, x2, y2)))
+    return;
+
   cairo_save (cr);
 
   spread = _gtk_css_number_value_get (shadow->spread, 0);
@@ -658,7 +664,6 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue   *shadow,
     {
       cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
       _gtk_rounded_box_path (padding_box, cr);
-
       outside = spread + clip_radius + MAX (fabs (x), fabs (y));
       clip_box = *padding_box;
       _gtk_rounded_box_grow (&clip_box, outside, outside, outside, outside);
@@ -667,12 +672,6 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue   *shadow,
       cairo_clip (cr);
     }
 
-  if (has_empty_clip (cr))
-    {
-      cairo_restore (cr);
-      return;
-    }
-
   box = *padding_box;
   _gtk_rounded_box_move (&box, x, y);